///////////////////////////////////////////////////////////////////////
//  CS 3716 (Winter 2012), Assignment #4                       		 //
//  Program File Name: RecDatabase.java                       		 //
//       Student Name: Jonathan Hart-Wall, Adam Murphy         		 //
//					   Yifu Liang, Joshua Dowling			   		 //
//         Login Name: jcwhw1, agm264 , n96yl, n23jdd                //
//              MUN #: 200933455, 200933133, 200565679, 200703684    //
///////////////////////////////////////////////////////////////////////

import java.util.ArrayList;
import java.util.Collections;
import java.io.*;


public class RecDatabase{
	
	private String name;
	private ArrayList<MovieRec> movies;
	private ArrayList<String> history;
	/**
	 * Constructor
	 * @param name The name of the Database.
	 * @param movies The recommendations in the database.
	 * @param history The editing history.
	 */
	public RecDatabase(String name, ArrayList<MovieRec> movies, ArrayList<String> history){
		this.name = name;
		this.movies = movies;
		this.history = history;
	}
	
	/**
	 * Constructor
	 * @param name the name of this RecDatabase being created.
	 */
	public RecDatabase(String name)
	{
		this.name = name;
		movies = new ArrayList<MovieRec>();
		history = new ArrayList<String>();
	}
	
	/**
	 * Returns name of database.
	 * @return Database name
	 */
	public String getName(){
		return name;
	}
	/**
	 * Merges a RecList with Database
	 * @param otherList an ArrayList of movies from a RecList
	 */
	public void merge(ArrayList<MovieRec> otherList){
		for(int i = 0; i < otherList.size();i++){
			boolean duplicate = false;
			for(int j = 0; j < movies.size();j++){
				if(otherList.get(i).getName().equalsIgnoreCase(movies.get(j).getName()) && otherList.get(i).getReleaseYear() == movies.get(j).getReleaseYear()){
					movies.set(j, otherList.get(i));
					duplicate = true;
				}
			}
			if (!duplicate)
				movies.add(otherList.get(i));
		}
	}
	/**
	 * Prints all movie recommendations, in their natural order.
	 */
	public String display() throws EmptyListException
	{
		if (movies.size() == 0)
			throw new EmptyListException();
		
		String display = "";
		for(int i = 0; i < movies.size(); i++){
			display = display + movies.get(i).toString() +"\n";
		}
		return display.trim();
	}
	/**
	 * Prints all movie recommendations, sorted by name, then release year.
	 */
	public String displaySorted() throws EmptyListException
	{
		if (movies.size() == 0)
			throw new EmptyListException();
		
		ArrayList<MovieRec> cloneList = new ArrayList<MovieRec>();
		
		for(int i =0; i < movies.size(); i++){
			cloneList.add(movies.get(i));
		}
		
		MRCompare comparator = new MRCompare();
		
		Collections.sort(cloneList, comparator);

		String display = "";
		
		for(int i = 0; i < cloneList.size(); i++){
			display = display + cloneList.get(i).toString() + "\n";
		}
		return display.trim();
	}
	/**
	 * Prints out editing history.
	 */
	public void viewHistory(){
		for(int i = 0; i < history.size(); i++){
			System.out.println(history.get(i));
		}
	}
	/**
	 * Searches the database for a specific movie.
	 * @param name Name of desired movie.
	 * @param releaseYear Release Year of desired movie.
	 * @return a MovieRec object if search was successful, a null object otherwise
	 */
	public MovieRec search(String name, int releaseYear) throws MovieNotFoundException, DatabaseIsEmptyException{
		if(movies.isEmpty()){
			//System.out.println("Database is Empty!");
			throw new DatabaseIsEmptyException("Database is Empty!");
		}
		MRCompare comparator = new MRCompare();
		for(int i = 0; i < movies.size();i++){
			if(movies.get(i).getName().equalsIgnoreCase(name) && movies.get(i).getReleaseYear() == releaseYear){
				return movies.get(i);
			}
		}
		throw new MovieNotFoundException(); // Might change this later to an exception.
	}
	/**
	 * Searches list for movies of desired genre
	 * @param genre Desired Genre
	 * @return ArrayList of MovieRec objects which contain the desired genre.
	 */
	public ArrayList<MovieRec> search(String genre) throws MovieNotFoundException, DatabaseIsEmptyException
	{
		ArrayList<MovieRec> searchResults = new ArrayList<MovieRec>();
		if(movies.isEmpty()){
			throw new DatabaseIsEmptyException();
		}
		String[] searchGenres = genre.split(" / ");

		for(int i = 0; i < movies.size(); i++){
			String[] genres = movies.get(i).getGenre().split(" / ");	
			boolean added = false;
			for(int j = 0; j < genres.length; j++)
			{
				for (int k = 0; k < searchGenres.length; k++)
				{
					if(genres[j].equalsIgnoreCase(searchGenres[k]))
					{
						searchResults.add(movies.get(i));
						added = true;
						break;
					}
				}
				if (added)
					break;
			}
		}
		if (searchResults.size() == 0)
			throw new MovieNotFoundException();
		return searchResults;
	}
	/**
	 * Adds editing history, recording any action performed by the user unto the RecDatabase.
	 * @param action Action that was performed.
	 * @param user User who performed action.
	 */
	public void addHistory(String action, String user){
		String hist = action +" " +user;
		history.add(hist);
	}	

	/**
	 * Updates the text file which contains information relevant to the DataBase.
	 * @param fileLocation Location of the text file.
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public void update(String fileLocation) throws FileNotFoundException, IOException
	{
		PrintWriter pw = new PrintWriter(new File(fileLocation + "//" + name + ".dat"));
		pw.println(name);
		pw.println();
		
		for (MovieRec movieRec : movies)
			pw.println(movieRec.getName() + "#" + movieRec.getReleaseYear() + "#" + movieRec.getGenre() + "#" + movieRec.getRating() + "#" + movieRec.getSubmitter());

		pw.println();
		
		for (String historyLine : history)
			pw.println(historyLine);
		pw.close();
	}
	
}
